package cn.cj.erp.service;

import cn.cj.erp.common.constants.SystemConstants;
import cn.cj.erp.common.enums.CaptchaTypeEnum;
import cn.cj.erp.common.exception.ServiceException;
import cn.cj.erp.common.redis.RedisCache;
import cn.cj.erp.common.redis.RedisKeyEnum;
import cn.cj.erp.common.utils.encrypt.Base64Util;
import cn.cj.erp.common.utils.id.IdUtil;
import cn.cj.erp.common.vo.login.CaptchaResponseVo;
import cn.hutool.core.util.ObjectUtil;
import com.google.code.kaptcha.Producer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 验证码业务处理
 *
 * @author jianchen
 */
@Slf4j
@Service
public class CaptureService {
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;
    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;
    @Resource
    private RedisCache redisCache;

    public CaptchaResponseVo getCaptureCode(CaptchaTypeEnum captchaType) {
        // 保存验证码信息
        String uuid = IdUtil.simpleUUID();
        redisCache.get(RedisKeyEnum.LOGIN_CAPTURE.getKey(uuid));
        String verifyKey = RedisKeyEnum.LOGIN_CAPTURE.getKey(uuid);

        String capStr, code;
        BufferedImage image;

        // 生成验证码
        if (CaptchaTypeEnum.MATH.equals(captchaType)) {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        } else if (CaptchaTypeEnum.CHAR.equals(captchaType)) {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        } else {
            throw new ServiceException("不支持的验证码格式：" + captchaType);
        }
        if(ObjectUtil.isNull(image)) {
            throw new ServiceException("验证码生成失败");
        }
        redisCache.set(verifyKey, code, SystemConstants.EXPIRE_MINUTE_CAPTCHA);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            log.info("验证码生成异常.", e);
            throw new ServiceException("验证码生成异常");
        }
        return new CaptchaResponseVo(uuid, Base64Util.encode(os.toByteArray()));
    }
}